const { readFileSync, } = require('fs')
const { join, dirname, isAbsolute, resolve } = require('path')

const { parse } = require('@babel/parser')
const traverse = require('@babel/traverse').default
const { transformFromAstSync } = require('@babel/core')

const parser = {
  /** 
   * @description 获取ast 树
   * @param {string} 文件绝对路径
   * @returns {object} {ast: 抽象语法树, source: 文件源内容}
   */
  getAst(filepath) {
    const file = readFileSync(filepath, 'utf-8')
    const ast = parse(file, { sourceType: 'module' })  // 解析成ast
    return { ast, source: file }
  },

  /**
   * @description 获取该模块下的所有依赖模块
   * @param {string} filepath 文件路径
   * @param {object} ast ast抽象语法树
   * @returns {array} deps --> 该模块依赖的所有模块
   */
  getDeps(filepath, ast) {
    // 文件夹路径
    const entryDir = dirname(filepath)

    // 该文件依赖的所有模块
    const deps = {}

    // 访问者对象
    const visitor = {
      ImportDeclaration(path) {
        const { node } = path;
        // 该文件依赖模块的绝对路径
        const absolutePath = resolve(entryDir, node.source.value)

        // 文件依赖模块收集
        deps[node.source.value] = absolutePath
      }
    }
    traverse(ast, visitor)

    return deps
  },

  /**
   * 
   * @param {object} ast 抽象语法树
   * @param {string} source 文件源内容
   * @returns {string} code -> 被编译后的文件内容
   */
  getCode(ast, source) {
    // 编译代码 - 让浏览器能够认识 - 加个插件 -> @babel/preset-env
    const { code } = transformFromAstSync(ast, source, {
      presets: ['@babel/preset-env']
    })

    return code
  }

}

module.exports = parser